package org.jboss.capedwarf.mail;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
import com.google.appengine.api.mail.MailService;
/**
* Converts GAE Message to JavaMail Message
*
* @author <a href="mailto:marko.luksa@gmail.com">Marko Luksa</a>
* @author <a href="mailto:ales.justin@jboss.org">Ales Justin</a>
*/
public class MessageConverter {
private static final Set<String> INVALID_ATTACHMENT_FILE_TYPES;
private MailService.Message message;
private Collection<String> to;
private Session session;
static {
INVALID_ATTACHMENT_FILE_TYPES = getInvalidAttachmentFileTypes();
}
protected static Set<String> getInvalidAttachmentFileTypes() {
String[] extensions = {"ade", "adp", "bat", "chm", "cmd", "com", "cpl", "exe",
"hta", "ins", "isp", "jse", "lib", "mde", "msc", "msp", "mst", "pif", "scr",
"sct", "shb", "sys", "vb", "vbe", "vbs", "vxd", "wsc", "wsf", "wsh"};
return new HashSet<>(Arrays.asList(extensions));
}
protected static boolean hasInvalidAttachmentFileType(String fileName) {
for (String ext : INVALID_ATTACHMENT_FILE_TYPES) {
if (fileName.endsWith("." + ext)) {
return true;
}
}
return false;
}
public MessageConverter(MailService.Message message, Session session) {
this(message, null, session);
}
public MessageConverter(MailService.Message message, Collection<String> to, Session session) {
this.message = message;
this.to = to;
this.session = session;
}
public Message convert() throws MessagingException {
MimeMessage msg = new MimeMessage(session);
msg.setSender(toAddress(message.getSender()));
msg.addRecipients(Message.RecipientType.TO, toAddressArray(to == null ? message.getTo() : to));
msg.addRecipients(Message.RecipientType.CC, toAddressArray(message.getCc()));
msg.addRecipients(Message.RecipientType.BCC, toAddressArray(message.getBcc()));
msg.setSubject(message.getSubject());
if (message.getHeaders() != null) {
for (MailService.Header header : message.getHeaders()) {
msg.addHeader(header.getName(), header.getValue());
}
}
addContentTo(msg);
return msg;
}
private void addContentTo(MimeMessage msg) throws MessagingException {
boolean hasAttachments = message.getAttachments() != null;
boolean hasTextBody = message.getTextBody() != null;
boolean hasHtmlBody = message.getHtmlBody() != null;
if (hasAttachments || hasHtmlBody) {
MimeMultipart mimeMultipart = new MimeMultipart();
if (hasTextBody) {
mimeMultipart.addBodyPart(createTextBodyPart(message.getTextBody()));
}
if (hasHtmlBody) {
mimeMultipart.addBodyPart(createHtmlBodyPart(message.getHtmlBody()));
}
if (hasAttachments) {
for (MailService.Attachment attachment : message.getAttachments()) {
mimeMultipart.addBodyPart(createAttachmentBodyPart(attachment));
}
}
msg.setContent(mimeMultipart);
} else {
msg.setContent(message.getTextBody(), "text/plain");
}
}
private MimeBodyPart createAttachmentBodyPart(MailService.Attachment attachment) throws MessagingException {
if (hasInvalidAttachmentFileType(attachment.getFileName())) {
throw new IllegalArgumentException(String.format("Invalid attachment file type: %s", attachment));
}
DataSource source = new ByteArrayDataSource(attachment.getData(), "application/octet-stream");
MimeBodyPart bodyPart = new MimeBodyPart();
bodyPart.setDataHandler(new DataHandler(source));
bodyPart.setFileName(attachment.getFileName());
return bodyPart;
}
private MimeBodyPart createTextBodyPart(String body) throws MessagingException {
MimeBodyPart textBodyPart = new MimeBodyPart();
textBodyPart.setText(body);
return textBodyPart;
}
private MimeBodyPart createHtmlBodyPart(String body) throws MessagingException {
MimeBodyPart htmlBodyPart = new MimeBodyPart();
htmlBodyPart.setContent(body, "text/html");
return htmlBodyPart;
}
private static Address[] toAddressArray(Collection<String> addresses) throws AddressException {
if (addresses == null)
return null;
Address[] result = new Address[addresses.size()];
int i = 0;
for (String address : addresses) {
result[i++] = toAddress(address);
}
return result;
}
private static Address toAddress(String address) throws AddressException {
return new InternetAddress(address);
}
}